package cn.gxufe.reliable.message.admin.schedule;

import cn.gxufe.reliable.message.admin.domain.RMessage;
import cn.gxufe.reliable.message.common.ResultVo;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixThreadPoolKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.function.Function;

/**
 * @author yingjie.rong
 **/
public abstract class AbstractSchedule {

    @Autowired
    protected RestTemplate restTemplate;

    public static final String CAN_CONFIRM_URL =  "/reliable/message/tryConfirm";
    public static final String FINISH_URL =  "/reliable/message/finish";
    public static final String CANCEL_URL =  "/reliable/message/cancel";

    public static final String TRY_FINISH_CANCEL =  "/reliable/message/tryFinishOrCancel";

    public static final ResultVo defaultValue = ResultVo.error("fallback");


   protected HystrixCommand.Setter getSetter(String name){
       if(StringUtils.isEmpty(name)){
           throw new IllegalArgumentException("HystrixCommand name is null !");
       }
       HystrixCommand.Setter setter = HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(name))
               .andCommandKey(HystrixCommandKey.Factory.asKey(name)).andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(name));
       return setter;
   }

    public <T> HystrixCommand<T>  getHystrixCommand(String name, Function<Void,T> function,T defaultValue){
       HystrixCommand<T> hystrixCommand = new HystrixCommand<T>(this.getSetter(name)) {
           @Override
           protected T run(){
              return function.apply(null);
           }
           @Override
           protected T getFallback() {
               return defaultValue;
           }
       };
       return hystrixCommand;
    }


    public  HystrixCommand<ResultVo>  getHystrixCommand(String name, Function<Void,ResultVo> function){
      return new HystrixCommand<ResultVo>(this.getSetter(name)){
          @Override
          protected ResultVo run(){
              return function.apply(null);
          }
          @Override
          protected ResultVo getFallback() {
              return defaultValue;
          }
      };
    }

    protected MultiValueMap<String, Object> getMultiValueMap(RMessage message){
        MultiValueMap<String, Object> requestEntity = new LinkedMultiValueMap<>();
        requestEntity.add("messageId", message.getId());
        requestEntity.add("key", message.getKey());
        requestEntity.add("header", message.getHeader());
        return requestEntity;
    }

}
